/*******************************************************************

   ParseWindow.c
	
	Does open a simple window with some easy gadgets and does
	parse the supplied arguments.
					
*********************************************************************/
#define PARENT
#include "/includes/Window.h"

// a template is already defined in our project.h (repeat ->)
// "AutoClose/N,SmallBorder/K,Quit/S"
// I want to do an additional work - we does parse the argument
// supplied to "SmallBorder" again. So we need an additional template

#define ON_OFF_TEMPLATE "0/S,OFF/S,FALSE/S,NO/S,1/S,ON/S,TRUE/S,YES/S"

// maximum count of items in our second template 
#define MAX_ON_OFF_COUNT 8

// if the result is higher or equal this, it means "on" - else "off" 
#define ON_CASE          4

// we allow to use the first 4 to turn the small border off - but here
// we don't do that, we show only the result of parsing to keep the
// source easy.

/********************************************************************/
// locale prototypes

BOOL OpenDOpusWin( WindowHandle *wh );

BOOL HandleWindow( WindowHandle *wh );

void ParseArguments( WindowHandle *wh, STRPTR args );

/********************************************************************/

void OwnWindow( STRPTR args, struct Screen *screen )
{
	WindowHandle          *wh;
	
	if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
	  {
		  wh->screen = screen;     // store the screen pointer
		  
		  if( OpenDOpusWin(wh) )   // open the window
	       {
				 // this we need to indicate that the second argument was empty
				 wh->result = 9;
				 
				 // since we can not show the results we does not need to parse
				 // the aguments earlier...
				 
				 ParseArguments( wh, args );
				 
				 // we copy now the arguments into the text gadget
		       // if we have supplied some...
				 
		       SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) args );
				 				 				 
		       while( TRUE ) 
			      {										 
				      wh->signals = Wait( 1 << wh->win->UserPort->mp_SigBit );   // wait for window events
						                				
				      if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
					        if( HandleWindow(wh) )
							       break;		// does end the while loop									   
					 
			      }
					
				 if( wh->fargs )           // free the FuncArgs
 				      DisposeArgs( wh->fargs );
			 
		       CloseConfigWindow( wh->win ); 
			 }
			 
		  FreeMemH( wh ); // free our memory
	  }	  					  
}

/********************************************************************/
// This function does open our window. We could have done this in the
// function OwnWindow() too, but we need this function later again.

BOOL OpenDOpusWin( WindowHandle *wh )
{
	NewConfigWindow ncfgwin;     // we need a NewConfigWindow structure too
	                             // of couse you could also allocate it with
										  // AllocMemH()...
	
	// and have to fill it
	
	ncfgwin.nw_Parent = wh->screen;  // open on this screen
	
	// getting a localized title...
	ncfgwin.nw_Title  = DOpusGetString( locale, MSG_WINDOW_TITLE );
	
	ncfgwin.nw_Dims   = &cfgwin; // a pointer to the ConfigWin structure
	ncfgwin.nw_Locale = locale;  // the module locale pointer (from modinit.c)
	ncfgwin.nw_Port   = NULL;    // we doesn't supply a port
	ncfgwin.nw_Font   = NULL;    // just taking the screen font
	ncfgwin.nw_Flags  = WINDOW_REQ_FILL      | // fill with stripple pattern
	                    WINDOW_AUTO_KEYS     | // handle keys automatic
							  WINDOW_SCREEN_PARENT;  // nw_Parent points to a screen
	
	if( (wh->win = OpenConfigWindow(&ncfgwin)) )   // open the window
	  {
		  if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
		     	 return TRUE;
					
		  CloseConfigWindow( wh->win );	//	in error case do not forget :-)
	  }
	
	return FALSE;
}


/********************************************************************/
// we does only close the window, if the closegadget was pressed
// if you want to close it within a gadget, you must only in the
// right case set "stop" to TRUE

BOOL HandleWindow( WindowHandle *wh )
{
	 BOOL stop = FALSE;
	 ULONG value;
	 
	 while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
		{
			switch( wh->imsg->Class )  // let's handle the IDCMP
			  {
				  case IDCMP_GADGETUP:
				                          switch( GET_ID(wh->imsg) )
	                                     {
														 case GADGET_ID_CYCLE:  // here we do show the results of our parsing or even a simple text
														                        
																						if( wh->fargs )
																						  {
																						     value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE );
																						     
																							  // value is now in range between 0 and 2 - just what we need... :) 
																							  
																						     switch( value )
																						       {
																									 case 0:
																									         sprintf( wh->buffer, "AutoClose value: %ld", wh->fargs->FA_Arguments[0] ? *(ULONG *) wh->fargs->FA_Arguments[0] : 0 );
																												break;
																												
																							       case 1: 
																									         if( wh->result == 9 )
																												    strcpy( wh->buffer, "No valid value for SmallBorder" );
																												else
																												  {
																													  if( wh->result < ON_CASE )
																													       strcpy( wh->buffer, "SmallBorder goes off" );
																													  else
																													       strcpy( wh->buffer, "SmallBorder goes on" );
																											     }
																									         break;
																												
																							       case 2: 
																									         sprintf( wh->buffer, "Switch QUIT was %ssupplied", wh->fargs->FA_Arguments[2] ? NULL : "not " ); 
																									         break;
																						       }
																						  }
																						else
																						      strcpy( wh->buffer, "No arguments supplied" );
																						
										                                    SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) wh->buffer );
										                                    break;
			
			                                  case GADGET_ID_OKAY:   // doing a message
			                                                         
																						SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
										                                    break;
										 			
			                                  case GADGET_ID_CANCEL: 
			                                                         SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
										                                    break;
		                                  }
																 
												  break;
									 
				  case IDCMP_CLOSEWINDOW:
				                          // we can not simply return here, the IntuiMessage must replied first
												  
									           stop = TRUE;
												  break;									 
			  }
								 
			ReplyWindowMsg( wh->imsg );  
							  
			// remember: You should not use any other routines
			// to get/reply the messages of this window than
			// GetWindowMsg() and ReplyWindowMsg() !!
	   }
						  	 
    return stop;
}

void ParseArguments( WindowHandle *wh, STRPTR args )
{
	  if( (wh->fargs = ParseArgs(FUNC1_TEMPLATE, args)) )
	    {
			 // now is already the main done
			 // if you want to access the result of parsing ->
			 
			 // for the first of the template (it's an ULONG value)
			 // result = *(ULONG *) wh->fargs->FA_Arguments[0];
			  
			 // for the second of the template (it's a STRPTR)
			 // result = wh->fargs->FA_Arguments[1];
			 
			 // for the last of the template (it's a BOOL)
			 // result = wh->fargs->FA_Arguments[2];
			 
			 // BUT REMEMBER :
			 // wh->fargs->FA_Arguments[x] itself is NULL, if the
			 // matching keyword was not supplied
			 // If you does not test this, an Enforcer hit is the
			 // "lowest" result you'll get... 
			 
			 // All clear ?
			 // Let's do it again -> we check now, if something
			 // and what of our ON_OFF_TEMPLATE was supplied to
			 // the SmallBorder argument 
			
			 FuncArgs *fargs; // we need a second pointer
			 			 			 
			 if( !wh->fargs->FA_Arguments[1] )
			      return;
			 
			 if( (fargs = ParseArgs(ON_OFF_TEMPLATE, (STRPTR) wh->fargs->FA_Arguments[1])) )
			   {
					// now we scan through the results and store them
					// as ULONG
										
					for( wh->result = 0; wh->result < MAX_ON_OFF_COUNT; wh->result++ )
					      if( fargs->FA_Arguments[wh->result] )
							     break;
					
					// we have now in wh->result:
					// - a value in range of 0 to 3 for any kind of "off"
					// - a value in range of 4 to 7 for any kind of "on"
					// - a value of 8, if nothing of the ON_OFF_TEMPLATE was supplied, but anything else...
					// - or even 9, if "SmallBorder" was not supplied or invalid
					
					DisposeArgs( fargs );
				}					
			   
			 // you may also take a look to HandleWindow()
			 // I do there our output within the cycle and text gadget 
			 
		 }
	
}